﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace ASPNETPerformance.App_BusinessLogic.Extensions {
    public class SiteMapExtensions {
        #region Class Variables

        List<SiteMapNode> currentBranch = null;

        #endregion

        #region Constructors

        public SiteMapExtensions() {

        }

        #endregion

        /// <summary>
        /// Read Only. Gets the Branch of the Site Map that holds the SiteMap.CurrentNode.
        /// Returns an empty list if SiteMap.CurrentNode == null
        /// </summary>
        public List<SiteMapNode> CurrentBranch {
            get {
                if ( currentBranch == null ) {
                    SiteMapNode cn = SiteMap.CurrentNode;
                    SiteMapNode n = cn;
                    currentBranch = new List<SiteMapNode>();
                    if ( cn != null ) {
                        while ( n.Url != SiteMap.RootNode.Url ) {
                            // I don't need to check for n.ParentNode == null
                            // because I know that:
                            // cn != null && n != SiteMap.RootNode
                            currentBranch.Add( n );
                            n = n.ParentNode;
                        }
                        // the while loop excludes the root node, so add it here
                        // I could add n, that should now be equal to SiteMap.RootNode, but this is clearer
                        currentBranch.Add( SiteMap.RootNode );

                        // The nodes were added in reverse order, from the CurrentNode up, so reverse them.
                        currentBranch.Reverse();
                    }
                }
                return currentBranch;
            }
        }

        /// <summary>
        /// Gets the CurrentBranch node at a given level.
        /// The level param is zero based.
        /// You must always check the return value for null!!
        /// </summary>
        /// <param name="level">Zero Based</param>
        /// <returns></returns>
        public SiteMapNode CurrentBranchNode( int level ) {
            List<SiteMapNode> cb = CurrentBranch;
            SiteMapNode n = null;
            int i = cb.Count;
            // Check that there are nodes in CurrentBranch
            if ( i > 0 ) {
                // Check that level is in range, ie, a valid index for CurrentBranch
                // I don't throw an exception 
                // because the level parameter could be a legitimate value, as Theseus doesn't know
                // in advance what levels there are in the CurrentBranch.  
                // As a result, this does not constitute an error, 
                // and therefore an error should NOT be thrown!
                // Returning null correctly represents this condition to Theseus.
                if ( !( level < 0 ) && !( level > i - 1 ) ) {
                    n = cb[ level ];
                }
            }
            return n;
        }

        public int CurrentNodeLevel {
            get {
                return CurrentBranch.Count - 1;
            }
        }

        /// <summary>
        /// For use with TreeView controls ONLY!!
        /// Gets the ValuePath of the current node.
        /// The ValuePath property depends on the node you start from.  
        /// As this method is building the ValuePath for the SiteMap.CurrentNode,
        /// we use CurrentBranch, and so we just need to know the LEVEL of the starting node
        /// rather than the starting node itself.
        /// </summary>
        /// <param name="startFromLevel"></param>
        /// <returns></returns>
        public string CurrentNodeValuePath( int startFromLevel ) {
            string s = string.Empty;
            List<SiteMapNode> ln = CurrentBranch;
            if ( ln.Count > 0 ) {
                for ( int i = startFromLevel; i == CurrentNodeLevel; i++ ) {
                    s = s + ln[ i ].Title + "/";
                }
            }
            return s;
        }
    }
}